Expand description
§Slog - Structured, extensible, composable logging for Rust
slog-rs
is an ecosystem of reusable components for structured, extensible,
composable logging for Rust.
slog
is slog-rs
’s main crate providing core components shared between
all other parts of slog-rs
ecosystem.
This is auto-generated technical documentation of slog
. For information
about project organization, development, help, etc. please see
slog github page
§Core advantages over log
crate
- extensible -
slog
crate provides core functionality: a very basic and portable standard feature-set based on opentrait
s. This allows implementing new features that can be independently published. - composable -
trait
s thatslog
exposes to provide extensibility are designed to be easy to efficiently reuse and combine. By combining different functionalities, each application can specify precisely when, where, and how to process logging data from an application and its dependencies. - flexible -
slog
does not constrain logging to just one globally registered backend. Parts of your application can handle logging in a customized way, or completely independently. - structured and both human and machine readable - By using the key-value data format and retaining its type information, the meaning of logging data is preserved. Data can be serialized to machine readable formats like JSON and sent to data-mining systems for further analysis, etc. On the other hand, when presenting on screen, logging information can be presented in aesthetically pleasing and easy to understand ways.
- contextual -
slog
’sLogger
objects carry set of key-value data pairs that contain the context of logging - information that otherwise would have to be repeated in every logging statement.
§slog
features
- performance oriented; read what makes slog
fast and see:
slog bench log
- lazily evaluation through closure values
- async IO support included: see
slog-async
crate
#![no_std]
support (with opt-outstd
cargo feature flag)- support for named format arguments (e.g.
info!(logger, "printed {line_count} lines", line_count = 2);
) for easy bridging between the human readable and machine-readable outputs - tree-structured loggers
- modular, lightweight and very extensible
- tiny core crate that does not pull any dependencies
- feature-crates for specific functionality
- using
slog
in library does not force users of the library to use slog (but provides additional functionality); see example how to useslog
in library
- backwards and forwards compatibility with
log
crate: seeslog-stdlog
crate - convenience crates:
- logging-scopes for implicit
Logger
passing: see slog-scope crate
- logging-scopes for implicit
- many existing core & community provided features:
- multiple outputs
- filtering control
- compile-time log level filter using cargo features (same as in
log
crate) - by level, msg, and any other meta-data
slog-envlogger
- port ofenv_logger
- terminal output, with color support: see
slog-term
crate
- compile-time log level filter using cargo features (same as in
- json
- syslog and journald support
- run-time configuration:
- run-time behavior change; see slog-atomic
- run-time configuration; see slog-config crate
§Notable details
Note: At compile time slog
by default removes trace and debug level
statements in release builds, and trace level records in debug builds. This
makes trace
and debug
level logging records practically free, which
should encourage using them freely. If you want to enable trace/debug
messages or raise the compile time logging level limit, use the following in
your Cargo.toml
:
slog = { version = ... ,
features = ["max_level_trace", "release_max_level_warn"] }
Root drain (passed to Logger::root
) must be one that does not ever return
errors. This forces user to pick error handing strategy.
Drain::fuse()
or Drain::ignore_res()
.
§Where to start
Drain
, Logger
and
log
macro are the most important elements of
slog. Make sure to read their respective documentation
Typically the biggest problem is creating a Drain
§Logging to the terminal
#[macro_use]
extern crate slog;
extern crate slog_term;
extern crate slog_async;
use slog::Drain;
fn main() {
let decorator = slog_term::TermDecorator::new().build();
let drain = slog_term::FullFormat::new(decorator).build().fuse();
let drain = slog_async::Async::new(drain).build().fuse();
let _log = slog::Logger::root(drain, o!());
}
§Logging to a file
#[macro_use]
extern crate slog;
extern crate slog_term;
extern crate slog_async;
use std::fs::OpenOptions;
use slog::Drain;
fn main() {
let log_path = "target/your_log_file_path.log";
let file = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(log_path)
.unwrap();
let decorator = slog_term::PlainDecorator::new(file);
let drain = slog_term::FullFormat::new(decorator).build().fuse();
let drain = slog_async::Async::new(drain).build().fuse();
let _log = slog::Logger::root(drain, o!());
}
You can consider using slog-json
instead of slog-term
.
slog-term
only coincidently fits the role of a file output format. A
proper slog-file
crate with suitable format, log file rotation and other
file-logging related features would be awesome. Contributions are welcome!
§Change logging level at runtime
#[macro_use]
extern crate slog;
extern crate slog_term;
extern crate slog_async;
use slog::Drain;
use std::sync::{Arc, atomic};
use std::sync::atomic::Ordering;
use std::result;
/// Custom Drain logic
struct RuntimeLevelFilter<D>{
drain: D,
on: Arc<atomic::AtomicBool>,
}
impl<D> Drain for RuntimeLevelFilter<D>
where D : Drain {
type Ok = Option<D::Ok>;
type Err = Option<D::Err>;
fn log(&self,
record: &slog::Record,
values: &slog::OwnedKVList)
-> result::Result<Self::Ok, Self::Err> {
let current_level = if self.on.load(Ordering::Relaxed) {
slog::Level::Trace
} else {
slog::Level::Info
};
if record.level().is_at_least(current_level) {
self.drain.log(
record,
values
)
.map(Some)
.map_err(Some)
} else {
Ok(None)
}
}
}
fn main() {
// atomic variable controlling logging level
let on = Arc::new(atomic::AtomicBool::new(false));
let decorator = slog_term::TermDecorator::new().build();
let drain = slog_term::FullFormat::new(decorator).build();
let drain = RuntimeLevelFilter {
drain: drain,
on: on.clone(),
}.fuse();
let drain = slog_async::Async::new(drain).build().fuse();
let _log = slog::Logger::root(drain, o!());
// switch level in your code
on.store(true, Ordering::Relaxed);
}
Why is this not an existing crate? Because there are multiple ways to achieve the same result, and each application might come with its own variation. Supporting a more general solution is a maintenance effort. There is also nothing stopping anyone from publishing their own crate implementing it.
Alternative to the above approach is slog-atomic
crate. It implements
swapping whole parts of Drain
logging hierarchy.
§Examples & help
Basic examples that are kept up-to-date are typically stored in
respective git repository, under examples/
subdirectory. Eg.
slog-term examples.
slog-rs wiki pages contain
some pages about slog-rs
technical details.
Source code of other software using slog-rs can be an useful reference.
Visit slog-rs gitter channel for immediate help.
§Migrating from slog v1 to slog v2
§Key-value pairs come now after format string
#[macro_use]
extern crate slog;
fn main() {
let drain = slog::Discard;
let root = slog::Logger::root(drain, o!());
info!(root, "formatted: {}", 1; "log-key" => true);
}
See more information about format at log
.
§slog-streamer
is gone
Create simple terminal logger like this:
#[macro_use]
extern crate slog;
extern crate slog_term;
extern crate slog_async;
use slog::Drain;
fn main() {
let decorator = slog_term::TermDecorator::new().build();
let drain = slog_term::FullFormat::new(decorator).build().fuse();
let drain = slog_async::Async::new(drain).build().fuse();
let _log = slog::Logger::root(drain, o!());
}
§Logging macros now takes ownership of values.
Pass them by reference: &x
.
Modules§
- ser
Deprecated Compatibility name to ease upgrading fromslog v1
Macros§
- Macro for building group of key-value pairs in
BorrowedKV
- Log critical level record
- Log debug level record
- Log error level record
- Log info level record
- Macro for build
KV
implementing type - Log message a logging record
- Macro for building group of key-value pairs:
OwnedKV
- Create
Record
at the given code location - Create
RecordStatic
at the given code location - Alias of
b
- Log critical level record (alias)
- Log debug level record (alias)
- Log error level record
- Log info level record (alias)
- Alias of
kv
- Log message a logging record (alias)
- Macro for building group of key-value pairs (alias)
- Create
Record
at the given code location (alias) - Create
RecordStatic
at the given code location (alias) - Log trace level record (alias)
- Log warning level record (alias)
- Log trace level record
- Log warning level record
Structs§
- Borrowed
KV
Drain
discarding everythingDrain
duplicating records into two otherDrain
s- A wrapper struct for serializing errors
Drain
filtering records- Explicit lazy-closure
Value
Drain
panicking on errorDrain
ignoring result- Opaque Key is a representation of a key.
Drain
filtering records byRecord
logging level- Logging handle used to execute logging statements
Drain
mapping error returned by anotherDrain
- Owned KV
- Chain of
SyncMultiSerialize
-s of aLogger
and its ancestors - Lazy
Value
that writes to Serializer - Handle passed to
PushFnValue
closure - One logging record
- Information that can be static in the given record thus allowing to optimize record creation to be done mostly at compile-time.
- Single pair
Key
andValue
Enums§
- Serialization Error
- Logging filtering level
- Logging level associated with a logging
Record
- Error returned by
Mutex<D : Drain>
Statics§
- Official capitalized logging (and logging filtering) level names
- Official capitalized logging (and logging filtering) short level names
Traits§
- Logging drain
- Function that can be used in
Filter
drain - Key-value pair(s) for log events
- Function that can be used in
MapErr
drain Drain + Send + RefUnwindSafe
boundDrain + Send + Sync + RefUnwindSafe
bound- This type is used to enforce
KV
s stored inLogger
s are thread-safe. Send + Sync + UnwindSafe
boundDrain + Send + Sync + UnwindSafe
bound- A value that can be serialized via serde
- Serializer
- Value that can be serialized
Type Aliases§
- Owned
KeyValue List Deprecated Compatibility name to ease upgrading fromslog v1
- Push
FnSerializer Deprecated Old name ofPushFnValueSerializer
- Push
Lazy Deprecated Compatibility name to ease upgrading fromslog v1
- Serialization
Result
- Serialize
Deprecated Compatibility name to ease upgrading fromslog v1
- Value
Serializer Deprecated Compatibility name to ease upgrading fromslog v1